import copy
import jwt
from passlib.context import CryptContext
from datetime import datetime, timedelta, timezone
from typing import Optional, TypeVar
from config.setting import ACCESS_TOKEN_EXPIRE_MINUTES, SECRET_KEY, ALGORITHM

# 使用bcrypt 报错未解决 修改
pwd_context = CryptContext(schemes=["argon2"], deprecated="auto")

T = TypeVar("T")
def verify_password(plain_password: str, hashed_password: str)->bool:
    """验证密码

    Args:
        plain_password (_type_): 明文
        hashed_password (bool): 密文

    Returns:
        _type_: _description_
    """
    return pwd_context.verify(plain_password, hashed_password)


def get_password_hash(password: str)->str:
    """获取密码的哈希值

    Args:
        password (str): _description_

    Returns:
        str: _description_
    """
    return pwd_context.hash(password)


def encode_data(data: T):
    return jwt.encode(data, SECRET_KEY, algorithm=ALGORITHM)

def decode_data(data: str):
    return jwt.decode(data, SECRET_KEY, algorithms=[ALGORITHM])




def encode_token(data: dict, expires_time: Optional[timedelta] = None):
    """编码token

    Args:
        data (dict): token中的数据
        expires_delta (Optional[timedelta], optional): 过期时间
    """
    to_encode_data = copy.deepcopy(data)
    if expires_time:
        expire = datetime.now(timezone.utc) + expires_time
    else:
        expire = datetime.now(timezone.utc) + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    to_encode_data.update({"exp": expire})
    return jwt.encode(to_encode_data, SECRET_KEY, algorithm=ALGORITHM)
    


def decode_token(encode_token: str):
    """解码token
        Args:
            encode_token (str): token 字符串
    """
    try:
        payload = jwt.decode(encode_token, SECRET_KEY, algorithms=[ALGORITHM])
        return payload
    except jwt.ExpiredSignatureError:
        return None
    

def checkck_token(token: str):
    """检查token是否有效

    Args:
        token (str): token字符串

    Returns:
        如果有效返回token 信息无效返回 None
    """
    payload = decode_token(token)
    if not payload:
        return None
    # 判断是否过期
    exp = payload.get("exp")
    print(exp)
    print(datetime.now(timezone.utc))
    if datetime.now(timezone.utc).timestamp() > exp:
        return None
    return payload